package com.furkid.service.controller;

import com.furkid.service.common.exception.BizException;
import com.furkid.service.constant.AjaxResult;
import com.furkid.service.domain.user.User;
import com.furkid.service.service.IUserService;
import com.furkid.service.service.token.TokenService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseCookie;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.Map;

@RestController
@RequestMapping("/api/auth")
public class UserController {
    @Autowired
    TokenService tokenService;

    @Autowired
    IUserService iUserService;

    @PostMapping("/login")
    public AjaxResult login(@RequestBody User user, HttpServletRequest request, HttpServletResponse response) {
        User resp_user = iUserService.userAccountLogin(user.getAccount(), user.getPassword());
        String ua = request.getHeader("User-Agent");
        String ip = request.getRemoteAddr();
        resp_user.setToken(tokenService.issueAccessToken(resp_user.getId(), ua, ip, Duration.ofMinutes(15)));
        String rt = tokenService.issueRefreshToken(resp_user.getId(), ua, ip, Duration.ofDays(7));
        ResponseCookie cookie = ResponseCookie.from("rt", rt)
                .httpOnly(true).path("/")
                .maxAge(Duration.ofDays(7))
                .sameSite("Lax").build();
        response.addHeader("Set-Cookie", cookie.toString());
        resp_user.setPassword(null);
        return AjaxResult.success("登录成功", resp_user);
    }

    @PostMapping("/refresh")
    public AjaxResult refresh(
            @CookieValue(value="rt", required=false) String rt,
            HttpServletResponse resp) {
        if (rt == null) {
            throw new BizException(401, "Missing refresh token");
        }

        Long uid = tokenService.verifyRefresh(rt);
        if (uid == null) {
            throw new BizException(401, "Refresh token invalid/expired");
        }

        // 发新的 access_token
        String at = tokenService.issueAccessToken(uid, "n/a", "n/a", Duration.ofMinutes(15));

        // 轮换 refresh_token（更安全；失败则认为已被并发使用/过期）
        String newRt = tokenService.rotateRefresh(rt, Duration.ofDays(7));
        if (newRt == null) {
            throw new BizException(401, "Refresh token rotated/expired");
        }

        // 覆盖 HttpOnly Cookie
        ResponseCookie cookie = ResponseCookie.from("rt", newRt)
                .httpOnly(true).sameSite("Lax").path("/")
                .maxAge(Duration.ofDays(7))
                .build();
        resp.addHeader("Set-Cookie", cookie.toString());

        // 返回新的 access_token
        return AjaxResult.success(Map.of("token", at));
    }

    @PostMapping("/logout")
    public AjaxResult logout(
            @RequestHeader(value = "Authorization", required = false) String auth,
            @CookieValue(value = "rt", required = false) String rt,
            HttpServletResponse response) {
        // 1) 删除 access token
        if (auth != null && auth.startsWith("Bearer ")) {
            String at = auth.substring(7);
            tokenService.deleteAccessToken(at);
        }

        // 2) 删除 refresh token Cookie 对应的 redis
        if (rt != null) {
            tokenService.deleteRefreshToken(rt);

            // 3) 覆盖 Cookie，使浏览器删除
            ResponseCookie cookie = ResponseCookie.from("rt", "")
                    .httpOnly(true)
                    .sameSite("Lax")
                    .path("/")
                    .maxAge(0)  // 让浏览器删除 Cookie
                    .build();
            response.addHeader("Set-Cookie", cookie.toString());
        }

        return AjaxResult.success("成功退出登录");
    }
}
